#lang racket


(require "../base/base.rkt")


(require "differenciation.rkt"
         "parametric.rkt")


(provide (struct-out surface)
         surface-tangent
         surface-normal
         surface-binormal
         make-simple-surface)


(define-struct (surface parametric) ())

(define (surface-tangent object-proc)
  (λ (u v)
    (differenciate-tangent object-proc u v)))

(define (surface-normal object-proc)
  (λ (u v)
    (let* ((ts (differenciate-tangent object-proc u v))
           (u (first ts))
           (v (second ts)))
      (pxp u v))))

(define (surface-binormal)
  (λ (u v)
    (raise unsupported "Binormal is undefined for surfaces")))

(define (make-simple-surface object-proc domain)
  (make-surface
   object-proc
   (surface-tangent object-proc)
   (surface-normal object-proc)
   (surface-binormal)
   domain))